#include "abf_flat.hpp"

namespace abf
{

flat::flat()
{
    m_flat = 0;
}

flat::flat(abf_flat_t* _flat)
{
    m_flat = _flat;
}

flat::~flat()
{
    clear();
}

void flat::clear()
{
    if (m_flat)
        abf_destroy(m_flat);
    m_flat = 0;
}

abf_flat_t* flat::internal_flat()
{
    if (m_flat)
        return m_flat;
    m_flat = abf_create();
    return m_flat;
}


flat& flat::operator=(const flat& c)
{
    // classical self-assignment test.
    if( &c == this )
        return *this;
    if (c.m_flat)
        abf_copy (internal_flat(), c.m_flat);
    else
        clear();
    return *this;
}

bool flat::ok () const
{
    return getstatus () == ABF_OK;
}

abf_status flat::getstatus () const
{
    if (!m_flat)
        return ABF_OK;
    return abf_getstatus (m_flat);
}

void flat::dump (int recurse)
{
    abf_dump (internal_flat(), recurse);
}

void flat::put_bool (const std::string& name, bool b)
{
    abf_put_bool (internal_flat(), name.c_str(), b);
}

void flat::put_uint8 (const std::string& name, u_int8 i)
{
    abf_put_uint8 (internal_flat(), name.c_str(), i);
}

void flat::put_sint8 (const std::string& name, s_int8 i)
{
    abf_put_sint8 (internal_flat(), name.c_str(), i);
}

void flat::put_uint16 (const std::string& name, u_int16 i)
{
    abf_put_uint16 (internal_flat(), name.c_str(), i);
}

void flat::put_sint16 (const std::string& name, s_int16 i)
{
    abf_put_sint16 (internal_flat(), name.c_str(), i);
}

void flat::put_uint32 (const std::string& name, u_int32 i)
{
    abf_put_uint32 (internal_flat(), name.c_str(), i);
}

void flat::put_sint32 (const std::string& name, s_int32 i)
{
    abf_put_sint32 (internal_flat(), name.c_str(), i);
}

void flat::put_string (const std::string& name, const std::string& s)
{
    abf_put_string (internal_flat(), name.c_str(), s.c_str());
}

void flat::put_float (const std::string& name, float f)
{
    abf_put_float (internal_flat(), name.c_str(), f);
}

void flat::put_double (const std::string& name, double d)
{
    abf_put_double (internal_flat(), name.c_str(), d);
}

void flat::put_flat (const std::string& name, abf_flat_t* sub)
{
    abf_put_flat (internal_flat(), name.c_str(), sub);
}

bool flat::get_bool (const std::string& name)
{
    return abf_get_bool (internal_flat(), name.c_str());
}

bool flat::get_bool (const std::string& name, bool optional)
{
    return abf_getopt_bool (internal_flat(), name.c_str(), optional);
}

u_int8 flat::get_uint8 (const std::string& name)
{
    return abf_get_uint8 (internal_flat(), name.c_str());
}

u_int8 flat::get_uint8 (const std::string& name, u_int8 optional)
{
    return abf_getopt_uint8 (internal_flat(), name.c_str(), optional);
}

s_int8 flat::get_sint8 (const std::string& name)
{
    return abf_get_sint8 (internal_flat(), name.c_str());
}

s_int8 flat::get_sint8 (const std::string& name, s_int8 optional)
{
    return abf_getopt_sint8 (internal_flat(), name.c_str(), optional);
}

u_int16 flat::get_uint16 (const std::string& name)
{
    return abf_get_uint16 (internal_flat(), name.c_str());
}

u_int16 flat::get_uint16 (const std::string& name, u_int16 optional)
{
    return abf_getopt_uint16 (internal_flat(), name.c_str(), optional);
}

s_int16 flat::get_sint16 (const std::string& name)
{
    return abf_get_sint16 (internal_flat(), name.c_str());
}

s_int16 flat::get_sint16 (const std::string& name, s_int16 optional)
{
    return abf_getopt_sint16 (internal_flat(), name.c_str(), optional);
}

u_int32 flat::get_uint32 (const std::string& name)
{
    return abf_get_uint32 (internal_flat(), name.c_str());
}

u_int32 flat::get_uint32 (const std::string& name, u_int32 optional)
{
    return abf_getopt_uint32 (internal_flat(), name.c_str(), optional);
}

s_int32 flat::get_sint32 (const std::string& name)
{
    return abf_get_sint32 (internal_flat(), name.c_str());
}

s_int32 flat::get_sint32 (const std::string& name, s_int32 optional)
{
    return abf_getopt_sint32 (internal_flat(), name.c_str(), optional);
}

std::string flat::get_string (const std::string& name)
{
    return abf_get_string (internal_flat(), name.c_str());
}

std::string flat::get_string (const std::string& name, const std::string& optional)
{
    return abf_getopt_string (internal_flat(), name.c_str(), optional.c_str());
}

float flat::get_float (const std::string& name)
{
    return abf_get_float (internal_flat(), name.c_str());
}

float flat::get_float (const std::string& name, float optional)
{
    return abf_getopt_float (internal_flat(), name.c_str(), optional);
}

double flat::get_double (const std::string& name)
{
    return abf_get_double (internal_flat(), name.c_str());
}

double flat::get_double (const std::string& name, double optional)
{
    return abf_getopt_double (internal_flat(), name.c_str(), optional);
}

flat flat::get_flat (const std::string& name)
{
    return flat(abf_get_flat(internal_flat(), name.c_str()));
}

}

